home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Select (Limited Edition)
/
Computer Select.iso
/
pcmag
/
v10n15
/
common.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-08-24
|
5KB
|
143 lines
UNIT common;
{*******************************************************************************
* *
* PCMFAT 1.1/READBOOT 1.1 Common routines *
* Copyright (c) 1991 Barry Simon *
* *
* First Published in PC Magazine, September 10, 1991 *
* *
* Requires Turbo Pascal 6.0 to compile (because of use of inline assembler) *
* *
*******************************************************************************}
{$A-}
INTERFACE
USES DOS;
TYPE
STR2 = STRING[2];
STR4 = STRING[4];
BootSectorType = RECORD
unused : ARRAY[0..1] OF Byte;
SystemID : STRING[8];
{we'll have to cheat to adjust the length
byte offset 2 is actually not used}
BytesPerSector : Word; {offset 11,12}
SectorsPerCluster : Byte; {offset 13}
SectorsBeforeData : Word; {offset 14,15}
NumFAT : Byte; {offset 16}
NumRootDir, {offset 17,18}
NumSectors : Word; {offset 19,20}
MediaDesc : Byte; {offset 21}
NumSecPerFAT, {offset 22,23}
NumSecPerTrack, {offset 24,25}
NumHeads : Word; {offset 26,27}
NumHidden, {offset 28-31}
LongNumSec : LongInt; {offset 32-35}
END;
FUNCTION Hex(B : Byte) : STR2;
FUNCTION HexWord(W : Word) : STR4;
PROCEDURE ReadSector(SecNum : LongInt);
CONST
Use3NibbleFAT : Boolean = False;
{If there is a 3NibbleFAT, it is simplest to read in three sectors
of FAT at a time}
VAR
PBlock : RECORD {needed for >32M disks under DOS 4/5}
SecNum : LongInt;
NumberToRead : Word;
BufferAddress : Pointer;
END;
Sector : ARRAY[0..8191] OF Byte; {512 needed in most cases; 8191
for safety in non-standard setups}
DriveNum : Byte; {0=A;1=B; etc}
BootSector : BootSectorType ABSOLUTE Sector;
IMPLEMENTATION
CONST
HexDigits : ARRAY[0..15] OF Char = '0123456789ABCDEF';
FUNCTION Hex(B : Byte) : STR2; {Changes byte to hex string}
BEGIN
Hex := HexDigits[B DIV 16]+HexDigits[B MOD 16];
END;
FUNCTION HexWord(W : Word) : STR4; {only used in PCMFAT}
BEGIN
HexWord := Hex(Hi(W))+Hex(Lo(W));
END;
PROCEDURE ReadSector(SecNum : LongInt);
VAR
NeedPBlock, ErrorOccurred : Boolean;
{DOS 4.0 introduced an extended call to Int 25/26H; this was needed
for partitions over 32M. It works with any drive so we always
use the extended call if DOS VER 4.0 or higher; this program will
not run as it stands with Compaq DOS 3.31 and larger than 32M
partitions}
BufferSeg, BufferOfs : Word;
FlagOut, ErrorOut, CXin, DXin : Word;
BEGIN
NeedPBlock := (Lo(DosVersion) > 3);
PBlock.SecNum := SecNum;
IF Use3NibbleFAT THEN PBlock.NumberToRead := 3 ELSE
PBlock.NumberToRead := 1; {# sectors}
PBlock.BufferAddress := @Sector;
IF NeedPBlock THEN BEGIN
BufferSeg := Seg(PBlock);
BufferOfs := Ofs(PBlock);
END ELSE BEGIN
BufferSeg := Seg(Sector);
BufferOfs := Ofs(Sector);
END;
IF NeedPBlock THEN CXin := $FFFF ELSE
IF Use3NibbleFAT THEN CXin := 3 ELSE CXin := 1;
IF NeedPBlock THEN DXin := 0 ELSE DXin := Word(SecNum);
{Sec Num must be a word under DOS < 4}
asm
push ax
push bx
push cx
push dx
push bp
push si
push di
push es
push ds
mov al, DriveNum
mov ah, 0
mov cx, CXin
mov dx, DXin
mov ds, BufferSeg
mov bx, BufferOfs
Int 25H
pushf
pop bx
popf {restores original flags and stack}
pop ds
pop es
pop di
pop si
pop bp
pop dx
pop cx
mov FlagOut, bx
mov ErrorOut, ax
pop bx
pop ax
END; {inline assembler statements}
ErrorOccurred := (FlagOut AND FCarry <> 0);
IF ErrorOccurred THEN BEGIN
WriteLn(' Fatal Error reading sector; program halted.');
WriteLn(' Error Number ', HexWord(ErrorOut));
Halt;
END;
END;
END.